iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
自我挑戰組

用 ODK 和 Access VBA 打造行動化資料收集流程系列 第 26

Day26: ODK Central API與Access VBA – Login與Logout

  • 分享至 

  • xImage
  •  

接下來幾天,我將提供自己設計的VBA程式,這些程式用來串接ODK Central API,可以達到使用Access VBA登入、登出ODK Central,下載問卷報告檔案,然後轉入Access資料庫中使用。

什麼是ODK Central API?

ODK Central 後端(Backend)是一個 RESTful API 伺服器,提供建立和管理 ODK 資料收集活動的關鍵功能。
它與Central前端(Frontend,一個獨立的前端介面)相結合,形成了 ODK Central,這是一個完整的用戶可安裝的 ODK 伺服器解決方案。
雖然Central前端是 ODK Central API 的主要使用者,但該伺服器提供的 API 是完全公開且通用的,可以在使用者介面中完成的任何操作,也都可以直接透過 API 完成。

連線階段認證

相關說明文件網址:
https://docs.getodk.org/central-api-authentication/

只有使用電子郵件帳號的使用者,可以透過這種方式進行身份驗證。
它主要由兩個步驟組成:
登入:提供電子郵件地址和密碼進行驗證,然後建立新連線階段,與其相關的是不記名通行證(Token)和過期時間,連線階段在建立連線後 24 小時過期。
使用連現階段:對於API的每個請求(request)都需要附加一個標頭「Authorization: Bearer {token}」,這將驗證該特定請求,是否屬於透過登入所建立的連線階段。

登入作業(Logging in)

為了讓使用者登入新連現階段,您必須提供 JSON 格式的憑證。出於安全原因,唯一可能的結果是成功或失敗,失敗時沒有提供詳細資訊。它僅適用於 GET 請求,並且僅適用於 HTTPS。

以下為VBA程式:

Function ODK_Login(str_user, str_password)
    On Error GoTo errHandle
    
    Dim strUrl As String
    Dim strReqBody As String
    Dim strResponse As String
    
    strUrlOpt = "/v1/sessions"
    
    strReqHeader1 = "Content-type"
    strReqHeader2 = "application/json"
    
    strMethod = "POST"
    strReqBody = Config("ODK_Login_Body")
    strReqBody = Replace(strReqBody, "{user}", str_user)
    strReqBody = Replace(strReqBody, "{password}", str_password)
    
    strUrl = ConfigCloud("F_ODK_Url") & strUrlOpt
        
    Set hReq = CreateObject("MSXML2.ServerXMLHTTP")
     
        With hReq
            .Open strMethod, strUrl, False
            .setRequestHeader strReqHeader1, strReqHeader2
            .send strReqBody
            While hReq.ReadyState <> 4
                DoEvents
            Wend
            strResponse = hReq.responseText
        End With
    
        JsonParser.InitScriptEngine
        Set root = JsonParser.DecodeJsonString(strResponse)
        strToken = JsonParser.GetProperty(root, "token")
        
        If Len(strToken) = 64 Then
            
            strCreatedAt = UTC_0600(JsonParser.GetProperty(root, "createdAt"))
            strExpiresAt = UTC_0600(JsonParser.GetProperty(root, "expiresAt"))
            
            Call ConfigLocalSave("ODK_Token", strToken, strResponse)
            Call ConfigLocalSave("ODK_Token_createdAt", strCreatedAt, "")
            Call ConfigLocalSave("ODK_Token_expiresAt", strExpiresAt, "")
            ODK_Login = True
        Else
            ODK_Login = False
        End If
        
Exit Function

errHandle:
    MsgBox Err.Number & ": " & Err.DESCRIPTION
    
End Function

以上程式中,有呼叫一些外部程式,以下進行說明:

讀取設定:Config()、ConfigLocal()、ConfigCloud()
儲存設定:ConfigSave()、ConfigLocalSave()、ConfigCloudSave()

Access VBA 的眉眉角角Day8: 於VBA中的設定值存取方法
https://ithelp.ithome.com.tw/m/articles/10185444

這裡有介紹Config()與ConfigSave()這對函數,而ConfigLocal()、ConfigCloud()則是此組函數的延伸,分別是儲存於temp資料夾內的access檔案的ConfigLocal(),以及使用SQL Server的ConfigCloud(),這可以讓不同場合,儲存不同的設定資訊。如果不是在公司環境使用,僅單機使用,其實用Config()即可。

ConfigCloud("F_ODK_Url")的內容為ODK Central的網址。

ODK_Login_Body內容:
使用此JSON內容進行登入作業

{
  "email": "{user}",
  "password": "{password}"
}

將UTC字串的日期時間資訊轉換成-6時區,由於該字串會長的像「2024-10-07T18:52:45.006Z」,這要整理過才能轉入Access中,且UTC時區為0,調整目前所在定時區才是的正確時間。這個可依照自己所在時區調整。

Public Function UTC_0600(strUTC) As String
    If IsNull(strUTC) Then
        UTC_0600 = ""
        Exit Function
    End If
    
    If Len(strUTC) = 29 Then
        iDiff = Mid(strUTC, 25, 2)
        If IsNumeric(iDiff) Then iDiff = Int(iDiff)
    Else
        iDiff = 0
    End If
    
    UTC_0600 = left(strUTC, 10) & " " & Mid(strUTC, 12, 8)
    UTC_0600 = DateAdd("h", -6 + iDiff, CDate(UTC_0600))
End Function

登出作業(Logging out)

成功登入後,會將登入的通行證(Token)存放在Access的ODK_Token上,接下來呼叫API時,都需要呼叫這文字串資料進行驗證,登出也不例外。

以下是登出作業時,使用的VBA程式碼:

Function ODK_LogOut()

    Dim strUrl As String
    Dim strReqBody As String
    
    strUrlOpt = "/v1/sessions/" & ConfigLocal("ODK_Token")
    
    strReqBody = ""
    
    strReqHeader1 = "Authorization"
    strReqHeader2 = "Bearer " & ConfigLocal("ODK_Token")
    
    strMethod = "DELETE"
    
    strUrl = ConfigCloud("F_ODK_Url") & strUrlOpt
        
    Set hReq = CreateObject("MSXML2.XMLHTTP")
        
        
        With hReq
            .Open strMethod, strUrl, False
            .setRequestHeader strReqHeader1, strReqHeader2
            .send strReqBody
            While hReq.ReadyState <> 4
                DoEvents
            Wend
            strResponse = hReq.responseText
            Debug.Print strResponse
            
            If InStr(strResponse, ":true") > 0 Then
                ODK_LogOut = True
                
                '把過期時間歸零,表示已登出
                Call ConfigLocalSave("ODK_Token_expiresAt", "", "")
                
            Else
                ODK_LogOut = False
            End If
        
        End With
    
End Function

上一篇
Day25: 表格語言(Form Language)
下一篇
Day27: ODK Central API與Access VBA – 專案管理
系列文
用 ODK 和 Access VBA 打造行動化資料收集流程30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言